#ifndef TESTBSTSORTING_HPP
#define TESTBSTSORTING_HPP
#include "BinarySearchTree.h"
#include <vector>
#include <ctime>

enum SortingMode
{
    Default = 0,
    PreDisordered = 1,
};

/**
 * @brief Disorder a vector.
 * @tparam DT 
 * @param  _arr             Target Vector.
 */
template <typename DT>
inline void DisorderVector(std::vector<DT> &_arr)
{
    srand((unsigned int)time(0));
    random_shuffle(_arr.begin(), _arr.end());
};

/**
 * @brief Sorting a vector based on binary-search-tree.
 * @tparam Comparable 
 * @param  _arr             The vector to be sorted.
 * @param  _mode            Default or pre-disordered.
 */
template <typename Comparable>
void BSTSorting(std::vector<Comparable> &_arr, SortingMode _mode = Default)
{
    if (_mode == SortingMode::PreDisordered)
        DisorderVector(_arr);
    BinarySearchTree<Comparable> *BST;
    BST = new BinarySearchTree<Comparable>();
    for (auto i : _arr)
        BST->insert(i);
    BST->print2Vector(_arr);
    delete BST;
}

/**
 * @brief A simple test for sorting N numbers based on binary-search-tree.
 * @param  N                An array ranging from 1 to N in reverse order.
 * @param  mode             Default or pre-disordered.
 * @param  displayResult    Print the sorted result or not.
 */
void TEST(int N, SortingMode mode, bool displayResult = false)
{
    std::vector<int> Vec;
    Vec.reserve(N);
    for (int i = N; i > 0; i--)
        Vec.push_back(i);
    clock_t start, end;
    start = clock();
    BSTSorting(Vec, mode);
    end = clock();
    std::cout << ((mode == SortingMode::Default) ? "Default" : "PreDisodered") << ": ";
    std::cout << "N = " << N << " takes " << double(end - start) / CLOCKS_PER_SEC << "s." << '\n';
    if (displayResult)
    {
        for (auto i : Vec)
            std::cout << i << '\t';
        std::cout << '\n';
    }
}

#endif // !TESTBSTSORTING_HPP